home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / qe4 / select.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-23  |  13.3 KB  |  685 lines

  1. // select.c
  2.  
  3. #include "qe3.h"
  4.  
  5. /*
  6. ===========
  7. Test_Ray
  8. ===========
  9. */
  10. #define    DIST_START    999999
  11. trace_t Test_Ray (vec3_t origin, vec3_t dir, int flags)
  12. {
  13.     brush_t    *brush;
  14.     face_t    *face;
  15.     float    dist;
  16.     trace_t    t;
  17.  
  18.     memset (&t, 0, sizeof(t));
  19.     t.dist = DIST_START;
  20.  
  21.     if (! (flags & SF_SELECTED_ONLY) )
  22.         for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
  23.         {
  24.             if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
  25.                 continue;
  26.             if (FilterBrush (brush))
  27.                 continue;
  28.             face = Brush_Ray (origin, dir, brush, &dist);
  29.             if (dist > 0 && dist < t.dist)
  30.             {
  31.                 t.dist = dist;
  32.                 t.brush = brush;
  33.                 t.face = face;
  34.                 t.selected = false;
  35.             }
  36.         }
  37.     for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
  38.     {
  39.         if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
  40.             continue;
  41.         if (FilterBrush (brush))
  42.             continue;
  43.         face = Brush_Ray (origin, dir, brush, &dist);
  44.         if (dist > 0 && dist < t.dist)
  45.         {
  46.             t.dist = dist;
  47.             t.brush = brush;
  48.             t.face = face;
  49.             t.selected = true;
  50.         }
  51.     }
  52.  
  53.     // if entites first, but didn't find any, check regular
  54.  
  55.     if ( (flags & SF_ENTITIES_FIRST) && t.brush == NULL)
  56.         return Test_Ray (origin, dir, flags - SF_ENTITIES_FIRST);
  57.  
  58.     return t;
  59. }
  60.  
  61.  
  62. /*
  63. ============
  64. Select_Brush
  65.  
  66. ============
  67. */
  68. void Select_Brush (brush_t *brush)
  69. {
  70.     brush_t    *b;
  71.     entity_t    *e;
  72.  
  73.     selected_face = NULL;
  74.     if (g_qeglobals.d_select_count < 2)
  75.         g_qeglobals.d_select_order[g_qeglobals.d_select_count] = brush;
  76.     g_qeglobals.d_select_count++;
  77.  
  78.     e = brush->owner;
  79.     if (e)
  80.     {
  81.         // select complete entity on first click
  82.         if (e != world_entity)
  83.         {
  84.             for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  85.                 if (b->owner == e)
  86.                     goto singleselect;
  87.             for (b=e->brushes.onext ; b != &e->brushes ; b=b->onext)
  88.             {
  89.                 Brush_RemoveFromList (b);
  90.                 Brush_AddToList (b, &selected_brushes);
  91.             }
  92.         }
  93.         else
  94.         {
  95. singleselect:
  96.             Brush_RemoveFromList (brush);
  97.             Brush_AddToList (brush, &selected_brushes);
  98.         }
  99.  
  100.         if (e->eclass)
  101.         {
  102.             UpdateEntitySel(brush->owner->eclass);
  103.         }
  104.     }
  105. }
  106.  
  107. /*
  108. ============
  109. Select_Ray
  110.  
  111. If the origin is inside a brush, that brush will be ignored.
  112. ============
  113. */
  114. void Select_Ray (vec3_t origin, vec3_t dir, int flags)
  115. {
  116.     trace_t    t;
  117.  
  118.     t = Test_Ray (origin, dir, flags);
  119.     if (!t.brush)
  120.         return;
  121.  
  122.     if (flags == SF_SINGLEFACE)
  123.     {
  124.         selected_face = t.face;
  125.         selected_face_brush = t.brush;
  126.         Sys_UpdateWindows (W_ALL);
  127.         g_qeglobals.d_select_mode = sel_brush;
  128.         return;
  129.     }
  130.  
  131.     // move the brush to the other list
  132.  
  133.     g_qeglobals.d_select_mode = sel_brush;
  134.  
  135.     if (t.selected)
  136.     {        
  137.         Brush_RemoveFromList (t.brush);
  138.         Brush_AddToList (t.brush, &active_brushes);
  139.     } else
  140.     {
  141.         Select_Brush (t.brush);
  142.     }
  143.  
  144.     Sys_UpdateWindows (W_ALL);
  145. }
  146.  
  147.  
  148. void Select_Delete (void)
  149. {
  150.     brush_t    *brush;
  151.  
  152.     selected_face = NULL;
  153.     g_qeglobals.d_select_mode = sel_brush;
  154.  
  155.     g_qeglobals.d_select_count = 0;
  156.     g_qeglobals.d_num_move_points = 0;
  157.     while (selected_brushes.next != &selected_brushes)
  158.     {
  159.         brush = selected_brushes.next;
  160.         Brush_Free (brush);
  161.     }
  162.  
  163.     // FIXME: remove any entities with no brushes
  164.  
  165.     Sys_UpdateWindows (W_ALL);
  166. }
  167.  
  168. void Select_Deselect (void)
  169. {
  170.     brush_t    *b;
  171.  
  172.     g_qeglobals.d_workcount++;
  173.     g_qeglobals.d_select_count = 0;
  174.     g_qeglobals.d_num_move_points = 0;
  175.     b = selected_brushes.next;
  176.  
  177.     if (b == &selected_brushes)
  178.     {
  179.         if (selected_face)
  180.         {
  181.             selected_face = NULL;
  182.             Sys_UpdateWindows (W_ALL);
  183.         }
  184.         return;
  185.     }
  186.  
  187.     selected_face = NULL;
  188.     g_qeglobals.d_select_mode = sel_brush;
  189.  
  190.     // grab top / bottom height for new brushes
  191.     if (b->mins[2] < b->maxs[2])
  192.     {
  193.         g_qeglobals.d_new_brush_bottom_z = b->mins[2];
  194.         g_qeglobals.d_new_brush_top_z = b->maxs[2];
  195.     }
  196.  
  197.     selected_brushes.next->prev = &active_brushes;
  198.     selected_brushes.prev->next = active_brushes.next;
  199.     active_brushes.next->prev = selected_brushes.prev;
  200.     active_brushes.next = selected_brushes.next;
  201.     selected_brushes.prev = selected_brushes.next = &selected_brushes;    
  202.  
  203.     Sys_UpdateWindows (W_ALL);
  204. }
  205.  
  206. /*
  207. ============
  208. Select_Move
  209. ============
  210. */
  211. void Select_Move (vec3_t delta)
  212. {
  213.     brush_t    *b;
  214.  
  215. // actually move the selected brushes
  216.     for (b = selected_brushes.next ; b != &selected_brushes ; b=b->next)
  217.         Brush_Move (b, delta);
  218. //    Sys_UpdateWindows (W_ALL);
  219. }
  220.  
  221. /*
  222. ============
  223. Select_Clone
  224.  
  225. Creates an exact duplicate of the selection in place, then moves
  226. the selected brushes off of their old positions
  227. ============
  228. */
  229. void Select_Clone (void)
  230. {
  231.     brush_t        *b, *b2, *n, *next, *next2;
  232.     vec3_t        delta;
  233.     entity_t    *e;
  234.  
  235.     g_qeglobals.d_workcount++;
  236.     g_qeglobals.d_select_mode = sel_brush;
  237.  
  238.     delta[0] = g_qeglobals.d_gridsize;
  239.     delta[1] = g_qeglobals.d_gridsize;
  240.     delta[2] = 0;
  241.  
  242.     for (b=selected_brushes.next ; b != &selected_brushes ; b=next)
  243.     {
  244.         next = b->next;
  245.         // if the brush is a world brush, handle simply
  246.         if (b->owner == world_entity)
  247.         {
  248.             n = Brush_Clone (b);
  249.             Brush_AddToList (n, &active_brushes);
  250.             Entity_LinkBrush (world_entity, n);
  251.             Brush_Build( n );
  252.             Brush_Move (b, delta);
  253.             continue;
  254.         }
  255.  
  256.         e = Entity_Clone (b->owner);
  257.         // clear the target / targetname
  258.         DeleteKey (e, "target");
  259.         DeleteKey (e, "targetname");
  260.  
  261.         // if the brush is a fixed size entity, create a new entity
  262.         if (b->owner->eclass->fixedsize)
  263.         {
  264.             n = Brush_Clone (b);
  265.             Brush_AddToList (n, &active_brushes);
  266.             Entity_LinkBrush (e, n);
  267.             Brush_Build( n );
  268.             Brush_Move (b, delta);
  269.             continue;
  270.         }
  271.         
  272.         // brush is a complex entity, grab all the other ones now
  273.  
  274.         next = &selected_brushes;
  275.  
  276.         for ( b2 = b ; b2 != &selected_brushes ; b2=next2)
  277.         {
  278.             next2 = b2->next;
  279.             if (b2->owner != b->owner)
  280.             {
  281.                 if (next == &selected_brushes)
  282.                     next = b2;
  283.                 continue;
  284.             }
  285.  
  286.             // move b2 to the start of selected_brushes,
  287.             // so it won't be hit again
  288.             Brush_RemoveFromList (b2);
  289.             Brush_AddToList (b2, &selected_brushes);
  290.             
  291.             n = Brush_Clone (b2);
  292.             Brush_AddToList (n, &active_brushes);
  293.             Entity_LinkBrush (e, n);
  294.             Brush_Build( n );
  295.             Brush_Move (b2, delta);
  296.         }
  297.  
  298.     }
  299.     Sys_UpdateWindows (W_ALL);
  300. }
  301.  
  302.  
  303.  
  304. /*
  305. ============
  306. Select_SetTexture
  307. ============
  308. */
  309. void Select_SetTexture (texdef_t *texdef)
  310. {
  311.     brush_t    *b;
  312.  
  313.     if (selected_face)
  314.     {
  315.         selected_face->texdef = *texdef;
  316.         Brush_Build(selected_face_brush);
  317.     }
  318.     else
  319.     {
  320.         for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  321.             if (!b->owner->eclass->fixedsize)
  322.                 Brush_SetTexture (b, texdef);
  323.     }
  324.     Sys_UpdateWindows (W_ALL);
  325. }
  326.  
  327.  
  328. /*
  329. ================================================================
  330.  
  331.   TRANSFORMATIONS
  332.  
  333. ================================================================
  334. */
  335.  
  336. void Select_GetBounds (vec3_t mins, vec3_t maxs)
  337. {
  338.     brush_t    *b;
  339.     int        i;
  340.  
  341.     for (i=0 ; i<3 ; i++)
  342.     {
  343.         mins[i] = 99999;
  344.         maxs[i] = -99999;
  345.     }
  346.  
  347.     for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  348.         for (i=0 ; i<3 ; i++)
  349.         {
  350.             if (b->mins[i] < mins[i])
  351.                 mins[i] = b->mins[i];
  352.             if (b->maxs[i] > maxs[i])
  353.                 maxs[i] = b->maxs[i];
  354.         }
  355. }
  356.  
  357. void Select_GetMid (vec3_t mid)
  358. {
  359.     vec3_t    mins, maxs;
  360.     int        i;
  361.  
  362.     Select_GetBounds (mins, maxs);
  363.     for (i=0 ; i<3 ; i++)
  364.         mid[i] = g_qeglobals.d_gridsize*floor ( ( (mins[i] + maxs[i])*0.5 )/g_qeglobals.d_gridsize );
  365. }
  366.  
  367. vec3_t    select_origin;
  368. vec3_t    select_matrix[3];
  369. qboolean    select_fliporder;
  370.  
  371. void Select_AplyMatrix (void)
  372. {
  373.     brush_t    *b;
  374.     face_t    *f;
  375.     int        i, j;
  376.     vec3_t    temp;
  377.  
  378.     for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  379.     {
  380.         for (f=b->brush_faces ; f ; f=f->next)
  381.         {
  382.             for (i=0 ; i<3 ; i++)
  383.             {
  384.                 VectorSubtract (f->planepts[i], select_origin, temp);
  385.                 for (j=0 ; j<3 ; j++)
  386.                     f->planepts[i][j] = DotProduct(temp, select_matrix[j])
  387.                         + select_origin[j];
  388.             }
  389.             if (select_fliporder)
  390.             {
  391.                 VectorCopy (f->planepts[0], temp);
  392.                 VectorCopy (f->planepts[2], f->planepts[0]);
  393.                 VectorCopy (temp, f->planepts[2]);
  394.             }
  395.         }
  396.         Brush_Build( b );
  397.     }
  398.     Sys_UpdateWindows (W_ALL);
  399. }
  400.  
  401.  
  402. void Select_FlipAxis (int axis)
  403. {
  404.     int        i;
  405.  
  406.     Select_GetMid (select_origin);
  407.     for (i=0 ; i<3 ; i++)
  408.     {
  409.         VectorCopy (vec3_origin, select_matrix[i]);
  410.         select_matrix[i][i] = 1;
  411.     }
  412.     select_matrix[axis][axis] = -1;
  413.  
  414.     select_fliporder = true;
  415.     Select_AplyMatrix ();
  416. }
  417.  
  418. void Select_RotateAxis (int axis, float deg)
  419. {
  420.     vec3_t    temp;
  421.     int        i, j;
  422.     vec_t    c, s;
  423.  
  424.     if (deg == 0)
  425.         return;
  426.  
  427.     Select_GetMid (select_origin);
  428.     select_fliporder = false;
  429.  
  430.     if (deg == 90)
  431.     {
  432.         for (i=0 ; i<3 ; i++)
  433.         {
  434.             VectorCopy (vec3_origin, select_matrix[i]);
  435.             select_matrix[i][i] = 1;
  436.         }
  437.         i = (axis+1)%3;
  438.         j = (axis+2)%3;
  439.         VectorCopy (select_matrix[i], temp);
  440.         VectorCopy (select_matrix[j], select_matrix[i]);
  441.         VectorSubtract (vec3_origin, temp, select_matrix[j]);
  442.     }
  443.     else
  444.     {
  445.         deg = -deg;
  446.         if (deg == -180)
  447.         {
  448.             c = -1;
  449.             s = 0;
  450.         }
  451.         else if (deg == -270)
  452.         {
  453.             c = 0;
  454.             s = -1;
  455.         }
  456.         else
  457.         {
  458.             c = cos(deg/180*3.14159);
  459.             s = sin (deg/180*3.14159);
  460.         }
  461.  
  462.         for (i=0 ; i<3 ; i++)
  463.         {
  464.             VectorCopy (vec3_origin, select_matrix[i]);
  465.             select_matrix[i][i] = 1;
  466.         }
  467.  
  468.         switch (axis)
  469.         {
  470.         case 0:
  471.             select_matrix[1][1] = c;
  472.             select_matrix[1][2] = -s;
  473.             select_matrix[2][1] = s;
  474.             select_matrix[2][2] = c;
  475.             break;
  476.         case 1:
  477.             select_matrix[0][0] = c;
  478.             select_matrix[0][2] = s;
  479.             select_matrix[2][0] = -s;
  480.             select_matrix[2][2] = c;
  481.             break;
  482.         case 2:
  483.             select_matrix[0][0] = c;
  484.             select_matrix[0][1] = -s;
  485.             select_matrix[1][0] = s;
  486.             select_matrix[1][1] = c;
  487.             break;
  488.         }
  489.     }
  490.  
  491.     Select_AplyMatrix ();
  492. }
  493.  
  494. /*
  495. ================================================================
  496.  
  497. GROUP SELECTIONS
  498.  
  499. ================================================================
  500. */
  501.  
  502. void Select_CompleteTall (void)
  503. {
  504.     brush_t    *b, *next;
  505.     int        i;
  506.     vec3_t    mins, maxs;
  507.  
  508.     if (!QE_SingleBrush ())
  509.         return;
  510.  
  511.     g_qeglobals.d_select_mode = sel_brush;
  512.  
  513.     VectorCopy (selected_brushes.next->mins, mins);
  514.     VectorCopy (selected_brushes.next->maxs, maxs);
  515.     Select_Delete ();
  516.  
  517.     for (b=active_brushes.next ; b != &active_brushes ; b=next)
  518.     {
  519.         next = b->next;
  520.         for (i=0 ; i<2 ; i++)
  521.             if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i])
  522.                 break;
  523.         if (i == 2)
  524.         {
  525.             Brush_RemoveFromList (b);
  526.             Brush_AddToList (b, &selected_brushes);
  527.         }
  528.     }
  529.     Sys_UpdateWindows (W_ALL);
  530. }
  531.  
  532. void Select_PartialTall (void)
  533. {
  534.     brush_t    *b, *next;
  535.     int        i;
  536.     vec3_t    mins, maxs;
  537.  
  538.     if (!QE_SingleBrush ())
  539.         return;
  540.  
  541.     g_qeglobals.d_select_mode = sel_brush;
  542.  
  543.     VectorCopy (selected_brushes.next->mins, mins);
  544.     VectorCopy (selected_brushes.next->maxs, maxs);
  545.     Select_Delete ();
  546.  
  547.     for (b=active_brushes.next ; b != &active_brushes ; b=next)
  548.     {
  549.         next = b->next;
  550.         for (i=0 ; i<2 ; i++)
  551.             if (b->mins[i] > maxs[i] || b->maxs[i] < mins[i])
  552.                 break;
  553.         if (i == 2)
  554.         {
  555.             Brush_RemoveFromList (b);
  556.             Brush_AddToList (b, &selected_brushes);
  557.         }
  558.     }
  559.     Sys_UpdateWindows (W_ALL);
  560. }
  561.  
  562. void Select_Touching (void)
  563. {
  564.     brush_t    *b, *next;
  565.     int        i;
  566.     vec3_t    mins, maxs;
  567.  
  568.     if (!QE_SingleBrush ())
  569.         return;
  570.  
  571.     g_qeglobals.d_select_mode = sel_brush;
  572.  
  573.     VectorCopy (selected_brushes.next->mins, mins);
  574.     VectorCopy (selected_brushes.next->maxs, maxs);
  575.  
  576.     for (b=active_brushes.next ; b != &active_brushes ; b=next)
  577.     {
  578.         next = b->next;
  579.         for (i=0 ; i<3 ; i++)
  580.             if (b->mins[i] > maxs[i]+1 || b->maxs[i] < mins[i]-1)
  581.                 break;
  582.         if (i == 3)
  583.         {
  584.             Brush_RemoveFromList (b);
  585.             Brush_AddToList (b, &selected_brushes);
  586.         }
  587.     }
  588.     Sys_UpdateWindows (W_ALL);
  589. }
  590.  
  591. void Select_Inside (void)
  592. {
  593.     brush_t    *b, *next;
  594.     int        i;
  595.     vec3_t    mins, maxs;
  596.  
  597.     if (!QE_SingleBrush ())
  598.         return;
  599.  
  600.     g_qeglobals.d_select_mode = sel_brush;
  601.  
  602.     VectorCopy (selected_brushes.next->mins, mins);
  603.     VectorCopy (selected_brushes.next->maxs, maxs);
  604.     Select_Delete ();
  605.  
  606.     for (b=active_brushes.next ; b != &active_brushes ; b=next)
  607.     {
  608.         next = b->next;
  609.         for (i=0 ; i<3 ; i++)
  610.             if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i])
  611.                 break;
  612.         if (i == 3)
  613.         {
  614.             Brush_RemoveFromList (b);
  615.             Brush_AddToList (b, &selected_brushes);
  616.         }
  617.     }
  618.     Sys_UpdateWindows (W_ALL);
  619. }
  620.  
  621. /*
  622. =============
  623. Select_Ungroup
  624.  
  625. Turn the currently selected entity back into normal brushes
  626. =============
  627. */
  628. void  Select_Ungroup (void)
  629. {
  630.     entity_t    *e;
  631.     brush_t        *b;
  632.  
  633.     e = selected_brushes.next->owner;
  634.  
  635.     if (!e || e == world_entity || e->eclass->fixedsize)
  636.     {
  637.         Sys_Status ("Not a grouped entity.", 0);
  638.         return;
  639.     }
  640.  
  641.     for (b=e->brushes.onext ; b != &e->brushes ; b=e->brushes.onext)
  642.     {
  643.         Brush_RemoveFromList (b);
  644.         Brush_AddToList (b, &active_brushes);
  645.         Entity_UnlinkBrush (b);
  646.         Entity_LinkBrush (world_entity, b);
  647.         Brush_Build( b );
  648.         b->owner = world_entity;
  649.     }
  650.  
  651.     Entity_Free (e);
  652.     Sys_UpdateWindows (W_ALL);
  653. }
  654.  
  655. /*
  656. ====================
  657. Select_MakeStructural
  658. ====================
  659. */
  660. void Select_MakeStructural (void)
  661. {
  662.     brush_t    *b;
  663.     face_t    *f;
  664.  
  665.     for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  666.         for (f=b->brush_faces ; f ; f=f->next)
  667.             f->texdef.contents &= ~CONTENTS_DETAIL;
  668.     Select_Deselect ();
  669.     Sys_UpdateWindows (W_ALL);
  670. }
  671.  
  672. void Select_MakeDetail (void)
  673. {
  674.     brush_t    *b;
  675.     face_t    *f;
  676.  
  677.     for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  678.         for (f=b->brush_faces ; f ; f=f->next)
  679.             f->texdef.contents |= CONTENTS_DETAIL;
  680.     Select_Deselect ();
  681.     Sys_UpdateWindows (W_ALL);
  682. }
  683.  
  684.  
  685.